﻿#$language = "Python"
#$interface = "1.0"

import os
import re
import sys

g_local_path = os.path.dirname(os.path.abspath(__file__))
if g_local_path not in sys.path:
    sys.path.insert(0, g_local_path)

import debug
import screen
from const import CONST_PROMPT_SFTP

class Sftp():
    '''Just for windows's SecureCRT sftp to linux'''

    def __init__(self, obj):
        self.obj = obj
        self.parent_tab = obj.GetScriptTab()
        self.log = debug.Log('sftp: ')
        self.log.w('connect to sftp ' + obj.Session.RemoteAddress)
        self.sftp = self.parent_tab.ConnectSftp()
        debug.sleep(1.0)
        prompt = screen.Prompt(CONST_PROMPT_SFTP, 1)
        self.crt = screen.Screen(self.sftp, prompt)
        del prompt

    def __del__(self):
        self.activate()
        self.sftp.Screen.Send('exit \r')
        self.log.w('close.')
        del self.crt
        del self.log
        while self.sftp.Session.Connected:
            debug.sleep(0.5)
        debug.sleep(1.0)
        self.sftp.Close()
        self.deactivate()

    def _check_path(self, path, command, location):
        rspd = self.crt.send('{0} "{1}"\r'.format(command, path))
        if 'Size:' in rspd:
            return True
        else:
            msg = 'check {0} path/file: "{1}" failed.'.format(location, path)
            self.log.w(msg)
            self.log.w(rspd.split(':').pop().strip())
            return False

    def _check_local_path(self, path):
        return self._check_path(path, 'ldetail', 'local')

    def _check_remote_path(self, path):
        return self._check_path(path, 'detail', 'remote')

    def _rename_file(self, source_name, target_name, command):
        remove_cmd = re.sub('mv', 'rm', command)
        self.log.w(
            'rename "{0}" to "{1}"'.format(source_name, target_name), end=' ')
        self.crt.send('{0} "{1}"\r'.format(remove_cmd, target_name))
        cmd_line = '{0} "{1}" "{2}"\r'.format(command, source_name, target_name)
        rspd = self.crt.send(cmd_line)
        if rspd:
            self.log.w("failed.", False)
            self.log.w(rspd)
            rslt = False
        else:
            self.log.w("successful.", False)
            rslt = True

    def activate(self):
        self.sftp.Activate()

    def deactivate(self):
        self.parent_tab.Activate()

    def cd(self, remote_path):
        if not self._check_remote_path(remote_path):
            return False
        self.crt.send('cd "{0}"\r'.format(remote_path))
        return True

    def lcd(self, local_path):
        if not self._check_local_path(local_path):
            return False
        self.crt.send('lcd "{0}"\r'.format(local_path))
        return True

    def get(self, remote_file):
        if not self._check_remote_path(remote_file):
            return False

        self.log.w("download file " + remote_file, end=' ')
        rspd = self.crt.send('get "{0}"\r'.format(remote_file))
        if 'bytes transferred' in rspd:
            self.log.w("successful.", False)
            return True
        else:
            self.log.w("failed.", False)
            self.log.w(rspd)
            return False

    def put(self, local_file):
        if not self._check_local_path(local_file):
            return False

        self.log.w("upload file " + local_file, end=' ')
        rspd = self.crt.send('put "{0}"\r'.format(remote_file))
        if 'bytes transferred' in rspd:
            self.log.w("successful.", False)
            return True
        else:
            self.log.w("failed.", False)
            self.log.w(rspd.splitlines().pop())
            return False

    def download(self, source_file, target_file):
        self.activate()
        self.log.w('start download file.\n' + \
                   '"{0}" ==> "{1}"'.format(source_file, target_file))
        local_path, local_file_name = os.path.split(target_file)
        remote_path, remote_file_name = os.path.split(source_file)
        
        if self.cd(remote_path) and self.lcd(local_path) \
                and self.get(remote_file_name):
            if local_file_name != remote_file_name:
                rslt = self._rename_file(remote_file_name, 
                                         local_file_name, 'lmv')
            else:
                rslt = True
        else:
            rslt = False

        self.deactivate()
        return rslt

    def upload(self, source_file, target_file):
        self.activate()
        self.log.w('start upload file.\n' + \
                   '"{0}" ==> "{1}"'.format(source_file, target_file))
        local_path, local_file_name = os.path.split(source_file)
        remote_path, remote_file_name = os.path.split(target_file)
        
        if self.cd(remote_path) and self.lcd(local_path) \
                and self.put(local_file_name):
            if local_file_name != remote_file_name:
                rslt = self._rename_file(local_file_name, 
                                         remote_file_name, 'mv')
            else:
                rslt = True
        else:
            rslt = False

        self.deactivate()
        return rslt
    #def download(self, source_file, target_file):
    #    self.activate()
    #    self.log.w('start download file.\n' + \
    #               '"{0}" ==> "{1}"'.format(source_file, target_file))
    #    local_path, local_file_name = os.path.split(target_file)
    #    remote_path, remote_file_name = os.path.split(source_file)
    #
    #    if not self._check_remote_path(source_file) or \
    #       not self._check_local_path(local_path):
    #        self.deactivate()
    #        return False
    #
    #    self.crt.send('cd "' + remote_path + '" \r')
    #    self.crt.send('lcd "' + local_path + '" \r')
    #
    #    self.log.w("download file", end=' ')
    #    rspd = self.crt.send('get "{0}"\r'.format(remote_file_name))
    #    if 'bytes transferred' in rspd:
    #        self.log.w("successful.", False)
    #    else:
    #        self.log.w("failed.", False)
    #        self.log.w(rspd)
    #        self.deactivate()
    #        return False
    #
    #    if local_file_name != remote_file_name:
    #        rslt = self._rename_file(remote_file_name, local_file_name, 'lmv')
    #    else:
    #        rslt = True
    #
    #    self.deactivate()
    #    return rslt
    #
    #def upload(self, source_file, target_file):
    #    self.activate()
    #    self.log.w('start upload file.\n' + \
    #        '"{0}" ==> "{1}"'.format(source_file, target_file))
    #    local_path, local_file_name = os.path.split(source_file)
    #    remote_path, remote_file_name = os.path.split(target_file)
    #
    #    if not self._check_remote_path(remote_path) or \
    #       not self._check_local_path(source_file):
    #        self.deactivate()
    #        return False
    #
    #    self.crt.send('cd "' + remote_path + '" \r')
    #    self.crt.send('lcd "' + local_path + '" \r')
    #
    #    self.log.w("upload file", end=' ')
    #    rspd = self.crt.send('put "{0}"\r'.format(local_file_name))
    #    if 'bytes transferred' in rspd:
    #        self.log.w("successful.", False)
    #    else:
    #        self.log.w("failed.", False)
    #        self.log.w(rspd.splitlines().pop())
    #        self.deactivate()
    #        return False
    #
    #    if local_file_name != remote_file_name:
    #        rslt = self._rename_file(local_file_name, remote_file_name, 'mv')
    #    else:
    #        rslt = True
    #
    #    self.deactivate()
    #    return rslt
